﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;
using SystemDiagramNew.TypeDefinition;
using SystemDiagramNew.Utils;

namespace SystemDiagramNew
{
	public class SystemDiagramManager
	{
		public SystemDiagramManager(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
			this.m_SortLevelList = this.m_Revit.Application.ActiveUIDocument.Document.GetSortLevels(double.MinValue, double.MaxValue);
		}

		public void LabelPipeDiameter()
		{
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			try
			{
				XYZ ptStart = null;
				XYZ ptEnd = null;
				XYZ ptInsert = null;
				double num = 0.0;
				double num2 = 0.0;
				double legendScale = 1.0;
				int diameter = 0;
				Element elem;
				while (this.SelelctPipeLine(out elem, ref ptStart, ref ptEnd, ref ptInsert, ref diameter, ref num, ref num2, ref legendScale))
				{
					DrawingKit.DrawingPipeDiameter(elem, diameter, ptStart, ptEnd, ptInsert, legendScale, this.m_Revit, activeView);
				}
			}
			catch (Exception ex)
			{
				Log.Error(new string[]
				{
					ex.Message
				});
			}
		}

		public void LabelPipeDiameter2()
		{
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			try
			{
				XYZ ptStart = null;
				XYZ ptEnd = null;
				XYZ ptInsert = null;
				double num = 0.0;
				double num2 = 0.0;
				double legendScale = 1.0;
				int diameter = 0;
				Element elem;
				while (this.SelelctPipeLine(out elem, ref ptStart, ref ptEnd, ref ptInsert, ref diameter, ref num, ref num2, ref legendScale))
				{
					Transaction transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document, "SystemDiagramAnnotate");
					transaction.Start();
					DrawingKit.DrawingPipeDiameter(elem, diameter, ptStart, ptEnd, ptInsert, legendScale, this.m_Revit, activeView);
					transaction.Commit();
				}
			}
			catch (Exception ex)
			{
				Log.Error(new string[]
				{
					ex.Message
				});
			}
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public void LabelPipeElevation()
		{
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			LabelPipeElevationForm labelPipeElevationForm = new LabelPipeElevationForm();
			labelPipeElevationForm.Show(CmdLabelPipeElevation._hWndRevit);
			int wMsg = 7;
			SystemDiagramManager.SendMessage(CmdLabelPipeElevation._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			try
			{
				XYZ xyz = null;
				XYZ xyz2 = null;
				XYZ ptSelect = null;
				double startElevation = 0.0;
				double endElevation = 0.0;
				double legendScale = 0.0;
				int num = 0;
				Element element;
				while (this.SelelctPipeLine(out element, ref xyz, ref xyz2, ref ptSelect, ref num, ref startElevation, ref endElevation, ref legendScale))
				{
					if (Geometry.IsEqual(xyz.X, xyz2.X, 0.0001))
					{
						MessageBox.Show("立管无法进行标记!", "盈建科提示");
					}
					else
					{
						DrawingKit.DrawingPipeElevation(startElevation, endElevation, xyz, xyz2, ptSelect, legendScale, (DrawingKit.LabelType)labelPipeElevationForm.TheLabelType(), this.m_Revit, activeView);
					}
				}
			}
			catch (Exception)
			{
				labelPipeElevationForm.Close();
				return;
			}
			labelPipeElevationForm.Close();
		}

		private bool SelelctPipeLine(out Element elem, ref XYZ ptStart, ref XYZ ptEnd, ref XYZ ptSelect, ref int diameter, ref double startElevation, ref double endElevation, ref double legendScale)
		{
			elem = null;
			Reference reference = null;
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				DetailLineFilter detailLineFilter = new DetailLineFilter();
				reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, detailLineFilter, "请选择要标注的系统图管线");
			}
			catch (Exception)
			{
				return false;
			}
			if (reference == null)
			{
				return false;
			}
			ptSelect = reference.GlobalPoint;
			Element element = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(reference);
			Line curve = (element as DetailLine).GeometryCurve as Line;
			ptStart = curve.GetEndPoint(0);
			ptEnd = curve.GetEndPoint(1);
			ElementId modelId = element.GetModelId();
			Pipe pipe = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(modelId) as Pipe;
			if (pipe == null)
			{
				return false;
			}
			diameter = pipe.GetDiameter();
			legendScale = 1.0;
			elem = pipe;
			return true;
		}

		private PipingSystemInfo GetPipeSystem(SelectionRange selectionRange, double angle, double xScale, double yScale, double zScale)
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Reference reference = null;
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				PipeFilter pipeFilter = new PipeFilter();
				reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, pipeFilter, "选择一根水管");
			}
			catch (Exception)
			{
				return null;
			}
			Pipe pipe = document.GetElement(reference) as Pipe;
			if (pipe == null)
			{
				return null;
			}
			List<ElementId> list = new List<ElementId>();
			if (selectionRange == SelectionRange.Box)
			{
				while (this.BoxSelectedElementsId(ref list))
				{
					if (list.Count == 0)
					{
						MessageBox.Show("范围为空，请重新选择", "盈建科提示");
					}
					if (list.Count != 0)
					{
						goto IL_9A;
					}
				}
				return null;
			}
			IL_9A:
			Level genLevel = this.m_Revit.Application.ActiveUIDocument.ActiveView.GenLevel;
			PipingSystem pipingSystem = pipe.MEPSystem as PipingSystem;
			IEnumerable<Element> elementSet = Enumerable.Empty<Element>();
			foreach (object obj in pipingSystem.PipingNetwork)
			{
				Element element = (Element)obj;
			}
			foreach (object obj2 in pipingSystem.Elements)
			{
				Element element2 = (Element)obj2;
			}
			return new SystemDiagramAnalyser(this.m_Revit).Analyse(pipingSystem.Name, elementSet, angle, xScale, yScale, zScale);
		}

		private void FilterSelectedElements(Element element, SelectionRange selectionRange, List<ElementId> elementsId, Level currentLevel, ref ElementSet elementSet)
		{
			if (selectionRange == SelectionRange.Box)
			{
				if (elementsId.FindIndex((ElementId s) => s.IntegerValue == element.Id.IntegerValue) != -1)
				{
					elementSet.Insert(element);
					return;
				}
			}
			else if (selectionRange == SelectionRange.Floor)
			{
				Level level;
				if (element.GetType() == typeof(Pipe))
				{
					level = (element as Pipe).ReferenceLevel;
				}
				else
				{
					level = element.GetYJKLevel();
				}
				if (level != null)
				{
					if (Geometry.IsEqual(level.Elevation, currentLevel.Elevation))
					{
						elementSet.Insert(element);
						return;
					}
				}
				else if (this.BelongToCurrentLevel(element))
				{
					elementSet.Insert(element);
					return;
				}
			}
			else
			{
				elementSet.Insert(element);
			}
		}

		private bool BelongToCurrentLevel(Element element)
		{
			bool result;
			try
			{
				Level genLevel = this.m_Revit.Application.ActiveUIDocument.ActiveView.GenLevel;
				XYZ point = (element.Location as LocationPoint).Point;
				int i = 0;
				int num = -1;
				while (i < this.m_SortLevelList.Count)
				{
					Level level = this.m_SortLevelList[i];
					if (Geometry.Greaterthan_Or_Equal(point.Z, level.Elevation))
					{
						num = i;
					}
					i++;
				}
				if (num != -1 && this.m_SortLevelList[num].Id.IntegerValue == genLevel.Id.IntegerValue)
				{
					result = true;
				}
				else
				{
					result = false;
				}
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		private bool BoxSelectedElementsId(ref List<ElementId> elementsId)
		{
			PickedBox pickedBox = null;
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				pickedBox = selection.PickBox((Autodesk.Revit.UI.Selection.PickBoxStyle)2, "选择范围");
			}
			catch (Exception)
			{
				return false;
			}
			double x = pickedBox.Min.X;
			double x2 = pickedBox.Max.X;
			double y = pickedBox.Min.Y;
			double y2 = pickedBox.Max.Y;
			if (Geometry.LessThan(pickedBox.Max.X, pickedBox.Min.X))
			{
				x = pickedBox.Max.X;
				x2 = pickedBox.Min.X;
			}
			if (Geometry.LessThan(pickedBox.Max.Y, pickedBox.Min.Y))
			{
				y = pickedBox.Max.Y;
				y2 = pickedBox.Min.Y;
			}
			XYZ xyz = new XYZ(x, y, -1000.0);
			XYZ xyz2 = new XYZ(x2, y2, 1000.0);
			BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(new Outline(xyz, xyz2), false);
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			foreach (Element element in new FilteredElementCollector(this.m_Revit.Application.ActiveUIDocument.Document, activeView.Id).WherePasses(boundingBoxIntersectsFilter).ToElements())
			{
				if (element.GetType() == typeof(Pipe))
				{
					elementsId.Add(element.Id);
				}
				else if (element.GetType() == typeof(FamilyInstance))
				{
					int integerValue = element.Category.Id.IntegerValue;
					if (integerValue == -2008055 || integerValue == -2008049 || integerValue == -2001160 || integerValue == -2008099 || integerValue == -2001140)
					{
						elementsId.Add(element.Id);
					}
				}
			}
			return true;
		}

		private readonly ExternalCommandData m_Revit;

		private readonly List<Level> m_SortLevelList = new List<Level>();
	}
}
